package main

import (
	"crypto/tls"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"time"
)

func Trans(dest io.WriteCloser, src io.ReadCloser){
	defer dest.Close()
	defer src.Close()
	io.Copy(dest, src)
}
func HTTPS(rw http.ResponseWriter, req *http.Request){
	destConn ,err := net.DialTimeout("tcp",req.Host,time.Second * 3)
	if err != nil{
		http.Error(rw,err.Error(),http.StatusServiceUnavailable)
		return
	}
	rw.WriteHeader(http.StatusOK)

	hijacker, ok := rw.(http.Hijacker)
	if !ok {
		http.Error(rw, "Hijacking not supported", http.StatusInternalServerError)
		return
	}

	clientConn, _, err := hijacker.Hijack()
	if err != nil {
		http.Error(rw, err.Error(), http.StatusServiceUnavailable)
	}
	go Trans(clientConn,destConn)
	go Trans(destConn,clientConn)

}
func HTTP(rw http.ResponseWriter, req *http.Request){
	log.Printf("%s %s %s",req.Method,req.Host,req.RemoteAddr)
	transport := http.DefaultTransport
	response , err :=transport.RoundTrip(req)
	if err != nil{
		http.Error(rw,err.Error(),http.StatusServiceUnavailable)
		return
	}
	for key , value := range response.Header{
		for _ , v := range value{
			rw.Header().Add(key,v)
		}
	}
	rw.WriteHeader(http.StatusOK)
	defer response.Body.Close()
	io.Copy(rw,response.Body)
}
func SelectMethod(rw http.ResponseWriter, req *http.Request) {
	log.Println("HTTPS")
	switch req.Method {
	case http.MethodConnect:
		HTTPS(rw,req)
	default:
		HTTP(rw,req)
	}
}

func main() {
	fmt.Println("Serve on :8000")
	//导入CA证书
	cer , err := tls.LoadX509KeyPair("cert.pem","key.pem")
	if err != nil{
		log.Fatalln(err)
	}
	//创建监听服务
	server := &http.Server{
		Addr: "127.0.0.1:8000",
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			//判断请求方式
			SelectMethod(w,r)
		}),
		//TLS配置证书
		TLSConfig: &tls.Config{Certificates: []tls.Certificate{cer}},
	}
	//开启服务
	server.ListenAndServe()
}